package com.yxy.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.yxy.system.service.IFileStorageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@Slf4j
@Service
public class FileStorageServiceImpl implements IFileStorageService {

    @Value("${file.temp.directory}")
    private String tempDirectory;

    @Value("${file.temp.cleanup.enabled}")
    private boolean cleanupEnabled;

    @Value("${file.temp.cleanup.maxAge}")
    private int maxAgeHours;

    /**
     * 初始化临时目录
     */
    @PostConstruct
    public void init() {
        try {
            Path tempPath = Paths.get(tempDirectory);
            if (!Files.exists(tempPath)) {
                Files.createDirectories(tempPath);
                log.info("创建临时目录: {}", tempDirectory);
            }

            // 启动定时清理任务
            if (cleanupEnabled) {
                cleanupTempFiles(maxAgeHours);
            }
        } catch (IOException e) {
            log.error("初始化临时目录失败: {}", tempDirectory, e);
        }
    }

    @Override
    public String saveToTemp(String fileId, MultipartFile file) throws IOException {
        validateFileId(fileId);

        // 生成唯一的文件名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = FileNameUtil.extName(originalFilename);
        String tempFilename = fileId + (fileExtension.isEmpty() ? "" : "." + fileExtension);

        Path tempFilePath = Paths.get(tempDirectory, tempFilename);

        // 保存文件
        file.transferTo(tempFilePath.toFile());

        log.info("文件保存到临时区域: {} -> {}", originalFilename, tempFilePath);
        return tempFilePath.toString();
    }

    @Override
    public String saveToTemp(String fileId, String localFilePath) throws IOException {
        validateFileId(fileId);

        File sourceFile = new File(localFilePath);
        if (!sourceFile.exists()) {
            throw new IOException("源文件不存在: " + localFilePath);
        }

        // 生成唯一的文件名
        String fileExtension = FileNameUtil.extName(localFilePath);
        String tempFilename = fileId + (fileExtension.isEmpty() ? "" : "." + fileExtension);

        Path tempFilePath = Paths.get(tempDirectory, tempFilename);

        // 复制文件到临时区域
        FileUtil.copy(sourceFile, tempFilePath.toFile(), true);

        log.info("本地文件复制到临时区域: {} -> {}", localFilePath, tempFilePath);
        return tempFilePath.toString();
    }

    @Override
    public String getTempFilePath(String fileId) {
        validateFileId(fileId);

        // 查找匹配的文件
        File tempDir = new File(tempDirectory);
        File[] files = tempDir.listFiles((dir, name) -> name.startsWith(fileId));

        if (files != null && files.length > 0) {
            return files[0].getAbsolutePath();
        }

        return null;
    }

    @Override
    public boolean existsInTemp(String fileId) {
        String filePath = getTempFilePath(fileId);
        return filePath != null && new File(filePath).exists();
    }

    @Override
    public boolean deleteFromTemp(String fileId) {
        String filePath = getTempFilePath(fileId);
        if (filePath != null) {
            File file = new File(filePath);
            if (file.exists()) {
                boolean deleted = file.delete();
                if (deleted) {
                    log.info("删除临时文件: {}", filePath);
                }
                return deleted;
            }
        }
        return false;
    }

    @Override
    public int cleanupTempFiles(int maxAgeHours) {
        File tempDir = new File(tempDirectory);
        if (!tempDir.exists() || !tempDir.isDirectory()) {
            return 0;
        }

        int deletedCount = 0;
        long maxAgeMillis = maxAgeHours * 60 * 60 * 1000L;
        long currentTime = System.currentTimeMillis();

        File[] files = tempDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    long lastModified = file.lastModified();
                    if (currentTime - lastModified > maxAgeMillis) {
                        if (file.delete()) {
                            deletedCount++;
                            log.debug("清理过期临时文件: {}", file.getName());
                        }
                    }
                }
            }
        }

        log.info("清理临时文件完成, 删除 {} 个文件", deletedCount);
        return deletedCount;
    }

    @Override
    public File getTempFile(String fileId) {
        String filePath = getTempFilePath(fileId);
        if (filePath != null) {
            File file = new File(filePath);
            if (file.exists()) {
                return file;
            }
        }
        return null;
    }

    @Override
    public long getTempFileSize(String fileId) {
        File file = getTempFile(fileId);
        return file != null ? file.length() : -1;
    }

    /**
     * 生成新的文件ID
     * @return 文件ID
     */
    public String generateFileId() {
        return IdUtil.fastSimpleUUID();
    }

    /**
     * 验证文件ID格式
     * @param fileId 文件ID
     */
    private void validateFileId(String fileId) {
        if (fileId == null || fileId.trim().isEmpty()) {
            throw new IllegalArgumentException("文件ID不能为空");
        }
        if (fileId.length() > 32) {
            throw new IllegalArgumentException("文件ID长度不能超过32字符");
        }
    }

    /**
     * 获取临时目录信息
     * @return 目录信息
     */
    public TempDirectoryInfo getTempDirectoryInfo() {
        File tempDir = new File(tempDirectory);
        TempDirectoryInfo info = new TempDirectoryInfo();
        info.setPath(tempDirectory);
        info.setExists(tempDir.exists());
        info.setDirectory(tempDir.isDirectory());

        if (tempDir.exists() && tempDir.isDirectory()) {
            File[] files = tempDir.listFiles();
            info.setFileCount(files != null ? files.length : 0);
            info.setTotalSize(calculateTotalSize(tempDir));
        }

        return info;
    }

    /**
     * 计算目录总大小
     * @param directory 目录
     * @return 总大小
     */
    private long calculateTotalSize(File directory) {
        long size = 0;
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    size += file.length();
                }
            }
        }
        return size;
    }

    /**
     * 临时目录信息类
     */
    public static class TempDirectoryInfo {
        private String path;
        private boolean exists;
        private boolean isDirectory;
        private int fileCount;
        private long totalSize;

        // getters and setters
        public String getPath() { return path; }
        public void setPath(String path) { this.path = path; }
        public boolean isExists() { return exists; }
        public void setExists(boolean exists) { this.exists = exists; }
        public boolean isDirectory() { return isDirectory; }
        public void setDirectory(boolean directory) { isDirectory = directory; }
        public int getFileCount() { return fileCount; }
        public void setFileCount(int fileCount) { this.fileCount = fileCount; }
        public long getTotalSize() { return totalSize; }
        public void setTotalSize(long totalSize) { this.totalSize = totalSize; }
    }


}
